package com.jftone.bh.app.config;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.jftone.bh.app.action.AdminAction;
import com.jftone.bh.app.action.BaseAction;
import com.jftone.bh.app.action.LoginAction;
import com.jftone.bh.app.action.UEditorAction;
import com.jftone.bh.app.model.SysLog;
import com.jftone.bh.app.service.AdminService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jftone.action.Action;
import org.jftone.action.render.Render;
import org.jftone.action.render.RenderFactory;
import org.jftone.component.BeanContext;
import org.jftone.config.ActionInterceptor;
import org.jftone.exception.ActionException;
import org.jftone.util.DateUtil;
import org.jftone.util.IData;
import org.jftone.util.IPv4Util;
import org.jftone.util.StringUtil;


public class BaseInterceptor implements ActionInterceptor {
	private Log log = LogFactory.getLog(BaseInterceptor.class);
	
	@Override
	public boolean before(Action action, String methodName, HttpServletRequest request, HttpServletResponse response) {
		boolean result = true;
		if(action instanceof LoginAction){
			return result;
		}
		try {
			BaseAction baseAction = (BaseAction) action;
			HttpSession session = request.getSession(false);
			if(session== null || session.getAttribute(SysConst.ADMIN_USER) == null){
				String requested = request.getHeader("X-Requested-With");
				if(requested != null && "XMLHttpRequest".equals(requested)){
					baseAction.send(SysConst.NO_LOGIN, "登录超时，请重新登录");
				}else{
					if(baseAction instanceof AdminAction && methodName.equals("manager")){
						baseAction.redirect("loginAction.do");
					}else{
						baseAction.loginTimeoutMsg();
					}
				}
				return false;
			}
			//设置菜单权限编码
			this.setRightCode(baseAction, methodName, request);
		} catch (Exception e) {
			log.error("action拦截[before]错误", e);
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean after(Action action, String methodName, HttpServletRequest request, HttpServletResponse responset) {
		if(methodName.startsWith("query") || methodName.equals("execute") || methodName.startsWith("get")
				|| methodName.equals("index") || methodName.startsWith("load") || methodName.startsWith("find")){
			return true;
		}
		HttpSession session = request.getSession(false);
		if(session == null || session.getAttribute(SysConst.ADMIN_USER)==null) return true;
		IData<String, Object> userData = (IData<String, Object>) session.getAttribute(SysConst.ADMIN_USER);
		String userNo = userData.getString("adminUser");
		BaseAction baseAction = (BaseAction) action;
		SysLog sysLog = new SysLog();
		sysLog.setUserNo(userNo);
		sysLog.setMenuCode(baseAction.getClass().getSimpleName());
		sysLog.setClientIp(IPv4Util.getIpAddr(baseAction.getRequest()));
		sysLog.setFuncCode(methodName);
		sysLog.setOperTime(DateUtil.getNow());
		sysLog.setData(baseAction.getData().toString());
		try {
			AdminService service = BeanContext.getBean(AdminService.class);
			service.saveSysLog(sysLog);
		} catch (Exception e) {
			log.error("用户操作日志信息保存错误", e);
		}
		return true;
	}

	@Override
	public boolean throwable(Action action, String methodName, HttpServletRequest request,
			HttpServletResponse response, ActionException ex) {
		String requested = request.getHeader("X-Requested-With");
		try {
			if(requested != null && "XMLHttpRequest".equals(requested)){
				BaseAction baseAction = (BaseAction) action;
				baseAction.send(SysConst.SYS_ERR, "服务器繁忙");
				return true;
			}
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("title", "请求发生错误");
			data.put("content", ex.getMessage());
			data.put("detail", ex.getCurStackTrace());
			data.put("url", null);
			Render render = RenderFactory.getInstance().getRender("common/error.html", data);
			render.setContext(request, response).render();
		} catch (Exception e) {
			log.error("action拦截[throwable]错误", e);
		}
		return true;
	}
	
	/**
	 * 检查并设置菜单权限编码
	 * @param action
	 * @param methodName
	 * @param request
	 */
	@SuppressWarnings("unchecked")
	private void setRightCode(Action action, String methodName, HttpServletRequest request) {
		if(action instanceof LoginAction){
			return;
		}
		String rightCode = request.getParameter(SysConst.RIGHT_CODE);
		if(null == rightCode || StringUtil.isBlank(rightCode)){
			return;
		}
		String rcKey = action.getClass().getSimpleName()+"."+methodName;
		Map<String, String> rcMap = null;
		HttpSession session = request.getSession();
		if(null == session.getAttribute(SysConst.RIGHT_CODE)){
			rcMap = new HashMap<String, String>();
		}else{
			rcMap = (Map<String, String>)session.getAttribute(SysConst.RIGHT_CODE);
		}
		if(rcMap.containsKey(rcKey)) return;
		rcMap.put(rcKey, rightCode);
		session.setAttribute(SysConst.RIGHT_CODE, rcMap);
	}

}
